/*
 * Copyright (C) 2004, Velocityme Partnership
 * ShowNodeAction.java
 *
 * Created on 10 July 2004, 02:49
 */

package com.velocityme.www.interfaces;

import com.velocityme.entity.Node;
import com.velocityme.entity.Activity;
import com.velocityme.entity.User;
import com.velocityme.enums.Permission;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.NodeLocal;
import com.velocityme.session.SearchLocal;
import com.velocityme.session.TaskLocal;
import com.velocityme.session.TreeLocal;
import com.velocityme.www.actionforms.NodeIdActionForm;
import com.velocityme.www.dto.ChildDTO;
import com.velocityme.www.utility.NodeUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

/**
 *
 * @author  bradloff
 */
public class ShowNodeAction extends DispatchAction  {
    
    /** Creates a new instance of ShowNodeAction */
    public ShowNodeAction() {
    }
    
    @Override
    public ActionForward execute(ActionMapping mapping, 
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        NodeIdActionForm nodeAF = (NodeIdActionForm)form;
        HttpSession session = request.getSession();
        Long nodeId = (Long)session.getAttribute("nodeId");
        if (nodeAF != null && nodeAF.getNodeId() != null)
            nodeId = nodeAF.getNodeId();
        request.setAttribute("nodeId", nodeId);
        request.setAttribute("selectedTab", "Node");
        return mapping.findForward("ACTION_NODE_SUCCESS");
    }
    
    static public void setupTreeDisplay(HttpSession session, Node node, String tab) {
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        Long nodeId = node.getId();
        SearchLocal searchLocal = lookupSearchBean();
        Set<Permission> permissionPKs = searchLocal.getAssignedPermissions(key, node);
        session.setAttribute("nodeId", nodeId);
        session.setAttribute("nodeValue", node);
        if (node instanceof Activity && permissionPKs.contains(Permission.TIME_CREATE))
            session.setAttribute("quickTime", Boolean.TRUE);
        else
            session.setAttribute("quickTime", null);
        TreeLocal treeLocal = lookupTreeBean();
        session.setAttribute("ancestorValues", treeLocal.getVisibleAncestorNodes(key, node));
        setupChildrenDTOs(session, node);
        session.setAttribute("tabValues", NodeUtil.getInstance().getNodeTabs(node.getClass().getSimpleName()));
        boolean isValidPasteNode = false;
        boolean isValidLinkNode = false;
        boolean isValidDependencyNode = false;
        boolean isValidDependantNode = false;
        Long markedNodeId = (Long)session.getAttribute("markedNodeId");
        if (markedNodeId != null) {
            NodeLocal nodeLocal = lookupNodeBean();
            Node markedNode = nodeLocal.findNode(key, markedNodeId);
            isValidPasteNode = treeLocal.isValidPasteNode(key, node, markedNode);
            isValidLinkNode = treeLocal.isValidLinkNode(key, node, markedNode);
            if (node instanceof Activity && markedNode instanceof Activity) {
                TaskLocal taskLocal = lookupTaskBean();
                Activity task = (Activity)node;
                Activity markedTask = (Activity)markedNode;
                isValidDependencyNode = taskLocal.isValidDependencyPair(key, markedTask, task);
                isValidDependantNode = taskLocal.isValidDependencyPair(key, task, markedTask);
            }
        }
        session.setAttribute("menuDTO", NodeUtil.getInstance().getMenu(key, node, permissionPKs, isValidPasteNode, isValidLinkNode, isValidDependencyNode, isValidDependantNode));
        session.setAttribute("buttonValues", NodeUtil.getInstance().getNodeButtons(node, tab, permissionPKs));
        session.setAttribute("selectedTabValue", tab);
    }
    
    static public void setupChildrenDTOs(HttpSession session, Node node) {
        KeyLocal key = (KeyLocal)session.getAttribute("sessionKey");
        TreeLocal treeLocal = lookupTreeBean();
        TaskLocal taskLocal = lookupTaskBean();
        session.setAttribute("childrenDTOs", getNodeDTOs(treeLocal.getVisibleChildrenNodes(key, node), key, taskLocal));
        session.removeAttribute("siblingDTOs");
        session.removeAttribute("linkedDTOs");
        session.removeAttribute("dependencyDTOs");
        session.removeAttribute("dependantDTOs");
        session.removeAttribute("bookmarkDTOs");
        if (node != null) {
            Collection<ChildDTO> siblingDTOs = getNodeDTOs(treeLocal.getVisibleSiblingNodes(key, node), key, taskLocal);
            if (siblingDTOs != null && siblingDTOs.size() != 0)
                session.setAttribute("siblingDTOs", siblingDTOs);
            Collection<ChildDTO> linkedDTOs = getNodeDTOs(treeLocal.getVisibleLinkedNodes(key, node), key, taskLocal);
            if (linkedDTOs != null && linkedDTOs.size() != 0)
                session.setAttribute("linkedDTOs", linkedDTOs);
            if (key.getShowBookmarks()) {
                Collection<ChildDTO> bookmarkDTOs = getNodeDTOs(treeLocal.getBookmarkNodes(key), key, taskLocal);
                session.setAttribute("bookmarkDTOs", bookmarkDTOs);
            }
            if (node instanceof Activity) {
                Activity task = (Activity) node;
                Collection<ChildDTO> dependencyDTOs = getNodeDTOs(treeLocal.getVisibleDependencyTasks(key, task), key, taskLocal);
                if (dependencyDTOs != null && dependencyDTOs.size() != 0)
                    session.setAttribute("dependencyDTOs", dependencyDTOs);
                Collection<ChildDTO> dependantDTOs = getNodeDTOs(treeLocal.getVisibleDependantTasks(key, task), key, taskLocal);
                if (dependantDTOs != null && dependantDTOs.size() != 0)
                    session.setAttribute("dependantDTOs", dependantDTOs);
            }
        }
    }
    
    static private Collection<ChildDTO> getNodeDTOs(Collection<Node> nodes, KeyLocal key, TaskLocal taskLocal) {
        if (nodes == null)
            return null;
        Collection<ChildDTO> nodeDTOs = new ArrayList<ChildDTO>();
        for (Node node: nodes) {
            boolean isActive = false;
            if (node instanceof Activity) {
                Activity task = (Activity)node;
                isActive = taskLocal.isTaskActive(key, task);
            }
            if (node instanceof User) {
                User user = (User)node;
                isActive = user.isEnabled();
            }
            nodeDTOs.add(new ChildDTO(node.getClass(), node.getName(), node.getId(), isActive));
        }
        return nodeDTOs;
    }

    static private SearchLocal lookupSearchBean() {
        try {
            Context c = new InitialContext();
            return (SearchLocal) c.lookup("java:comp/env/SearchBean");
        } catch (NamingException ne) {
            Logger.getLogger(ShowNodeAction.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private TreeLocal lookupTreeBean() {
        try {
            Context c = new InitialContext();
            return (TreeLocal) c.lookup("java:comp/env/TreeBean");
        } catch (NamingException ne) {
            Logger.getLogger(ShowNodeAction.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private TaskLocal lookupTaskBean() {
        try {
            Context c = new InitialContext();
            return (TaskLocal) c.lookup("java:comp/env/TaskBean");
        } catch (NamingException ne) {
            Logger.getLogger(ShowNodeAction.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    static private NodeLocal lookupNodeBean() {
        try {
            Context c = new InitialContext();
            return (NodeLocal) c.lookup("java:comp/env/NodeBean");
        } catch (NamingException ne) {
            Logger.getLogger(ShowNodeAction.class.getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

}
